
import 'dart:math';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';

import 'weather_bean.dart';

const MIN_HEIGHT = 300.0 ;

class DetailWidget extends StatefulWidget {
  String _title;
  double _height ;
  DetailWidget(this._title, this._height);
  @override
  State<StatefulWidget> createState() => _TodayState();
}

class _TodayState extends State<DetailWidget> with TickerProviderStateMixin {
  AnimationController _todayController;
  AnimationController _otherDayController;
  Animation<double> _todayAnimation ;
  Animation<double> _otherDayAnimation ;
  bool _todayExpand ;
  bool _otherDayExpand ;
  bool _animationNotCompleted ;
  double _todayContainerHeight = MIN_HEIGHT ;
  bool _pageChanged = false ;

  double _screenWidth = 0.0;
  double _screenHeight = 0.0;
  double _otherDayOffsetX = 0.0 ;

  ScrollController _scrollController ;
  String _selectedDayKey = "";
  double _offsetOneDayExplore = 0.0 ;

  @override
  void initState() {
    super.initState();
    _animationNotCompleted = false ;
    _todayExpand = false;
    _otherDayExpand = false;
    _selectedDayKey = "";
    _scrollController = ScrollController();
  }

  _changeStatus(){
    if(!_animationNotCompleted) {
      _pageChanged = true;
      _todayController = AnimationController(vsync: this, duration: Duration(milliseconds: 200));
      _todayAnimation = Tween(begin: _todayExpand ? 1.0 : 0.0, end: _todayExpand? 0.0: 1.0).animate(_todayController)
        ..addListener(() {
          _todayContainerHeight = _todayAnimation.value * (widget._height - MIN_HEIGHT) + MIN_HEIGHT;
          setState(() {});
        })
        ..addStatusListener((status) {
          if (status == AnimationStatus.completed) {
            _animationNotCompleted = false;
            _todayExpand = !_todayExpand ;
          }
          if(status == AnimationStatus.forward) {
            _animationNotCompleted = true;
          }
        });
      _todayController.forward();
    }

  }

  _otherOpen(String key){
    if(!_animationNotCompleted) {
      _selectedDayKey = key ;
      _otherDayController = AnimationController(vsync: this, duration: Duration(milliseconds: 200));
      _otherDayAnimation = CurvedAnimation(parent: _otherDayController, curve: Curves.easeInOut);
      _otherDayAnimation = Tween(begin: _otherDayExpand ? 1.0 : 0.0, end: _otherDayExpand ? 0.0: 1.0).animate(_otherDayAnimation)
        ..addListener(() {
          _otherDayOffsetX = _otherDayAnimation.value;
          setState(() {});
        })
        ..addStatusListener((status) {
          if (status == AnimationStatus.completed) {
            _animationNotCompleted = false;
            _otherDayExpand = !_otherDayExpand ;
          }
          if(status == AnimationStatus.forward) {
            _animationNotCompleted = true;
          }
        });
      _otherDayController.forward();
      _scrollToIndex(key);
    }
  }

  void _scrollToIndex(String key) {
     var offset = _getScrollViewIndex(key) * (130.0 + 10.0 + 1.5);
    _scrollController.animateTo(offset , duration: new Duration(milliseconds: 200), curve: Curves.ease);
  }

  _closeTab(){
    if(_otherDayOffsetX != 0.0) {
      _otherOpen(_selectedDayKey);
    }
  }

  @override
  Widget build(BuildContext context) {
    _screenWidth = MediaQuery.of(context).size.width;
    _screenHeight = MediaQuery.of(context).size.height;
    return SizedBox(
      height: _screenHeight - (20.0 + 20.0 + 28.0 + 50.0 + 20.0 + 48.0),
      width: _screenWidth + 27.0,
      child: Stack(
          children: <Widget>[
            Container(
                height: _todayContainerHeight,
                width: double.infinity,
                margin: const EdgeInsets.all(20.0),
                child: _buildDetail()
            ),
            _buildMore(),
            Positioned(
                top: 0.0,
                left: _screenWidth / 2 - 52.0 / 2,
                child: Opacity(
                    opacity: _otherDayOffsetX ?? 0.0,
                    child: GestureDetector(
                      onTap: _closeTab,
                      child: SizedBox(
                          width: 52.0,
                          height: 52.0,
                          child: DecoratedBox(decoration: BoxDecoration(
                              borderRadius: BorderRadius.all(
                                  Radius.circular(52.0)),
                              color: Colors.white,
                              boxShadow: <BoxShadow>[
                                BoxShadow(color: Color(0xFFEDF0F5))
                              ]
                          ),
                              child: Transform.rotate(
                                  angle: pi / 2 * (_otherDayOffsetX ?? 0.0),
                                  origin: Offset(0.0, 0.0),
                                  child: Icon(
                                      Icons.close, color: Color(0xFFFF0090))
                              )
                          )
                      ),
                    )
                )
            ),
          ])
    );
  }

  Widget _buildDetail(){
    var value = _todayAnimation?.value ?? 0.0 ;
    var padding = _screenWidth / 2 - 100.0 / 2 - 20 ;
    var size = padding * 2 ;
    var offsetX = padding;
    if(_pageChanged) {
      offsetX = padding - size * value;
    }
    print("change expand=$_todayExpand, value=$value, pading=$padding, offsetX=$offsetX");
    return GestureDetector(
      onTap: _changeStatus,
      child:  Container(
          decoration: BoxDecoration(
            borderRadius: BorderRadius.all(Radius.circular(20.0)),
            color: Color(0xFF5D50FE),
          ),
          constraints: BoxConstraints(maxHeight: _todayContainerHeight),
          height: _todayContainerHeight,
          child: Stack(
            alignment: Alignment.center,
            children: <Widget>[
              SizedBox(
                height: 200.0,
                width: 200.0,
                child: Transform.translate(
                  offset: Offset(0 - value * 50.0, 0 + value * 50.0),
                  child: Transform.scale(
                    scale: 1.0 + (_todayAnimation?.value ?? 0.0),
                    child: Image.asset("images/bg_1.png", height: 200.0, width: 200.0,fit: BoxFit.cover,),
                  ),
                ),
              ),
              Padding(
                padding: const EdgeInsets.all(30.0),
                child: Column(
                  children: <Widget>[
                    Text("25°", style: TextStyle(color: Colors.white, fontSize: 120.0,),),
                    Text("Clouds & sun", style: TextStyle(color: Colors.white, fontSize: 23.0,),),
                    SizedBox(height: 10.0,),
                    Text("Humldlty°", style: TextStyle(color: Colors.white, fontSize: 19.0,fontWeight: FontWeight.bold),),
                    SizedBox(height: 5.0,),
                    Text("35°", style: TextStyle(color: Colors.white30, fontSize: 27.0,),),
                  ],
                ),
              ),
              Positioned(
                child: Opacity(
                  opacity: value,
                  child: Column(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      SizedBox(height: 30.0,),
                      Text("Rain Starting in 13 min", style: TextStyle(color: Colors.white, fontSize: 23.0,),),
                      Text("Nearest precip: 6 mi to the west", style: TextStyle(color: Colors.white, fontSize: 12.0,),),
                    ],
                  ),
                ),
                bottom: 130.0,
              ),
              Transform.translate(
                offset: Offset(offsetX - 30.0 + value * 30.0, _todayContainerHeight / 2 - 75.0 / 2 - 30.0 - value * 20.0),
                child: Image.asset("images/sun_1.png"),
              ),
              Transform.translate(
                offset: Offset(offsetX, _todayContainerHeight / 2 - 75.0 / 2),
                child: Image.asset("images/cloud.png", height: 120.0, width: 120.0,),
              ),
            ],
          )
      )
    );
  }

  Widget _buildMore() {
    var moreHeight = widget._height - MIN_HEIGHT;
    var minHeight = moreHeight - 50.0;
    var maxHeight = _screenHeight - 78 - minHeight - 90.0;
    return Positioned(
      bottom: 0.0,
      height: minHeight + _otherDayOffsetX * maxHeight,
      width: _screenWidth,
      child: Transform.translate(
        offset: Offset(0.0, moreHeight * (_todayAnimation?.value ?? 0.0)),
        child: Opacity(opacity: 1.0 - (_todayAnimation?.value ?? 0.0),
          child: Column(
              children: <Widget>[
                Opacity(
                  opacity: 1.0 - _otherDayOffsetX,
                  child: Text("Next 15 Days", style: TextStyle(color: Color(0xFF130E51),
                      fontSize: 19.0,
                      fontWeight: FontWeight.bold),),
                ),
                SizedBox(height: 5.0,),
                Container(
                  height: minHeight -50.0 + _otherDayOffsetX * maxHeight,
                  child: CustomScrollView(
                    shrinkWrap: true,
                    scrollDirection: Axis.horizontal,
                    controller: _scrollController,
                    // 内容
                    slivers: <Widget>[
                      SliverPadding(
                        padding: const EdgeInsets.all(5.0),
                        sliver: SliverList(
                          delegate: SliverChildListDelegate(
                              WeatherBean.getDefaultDateData().map((bean) {
                                return _buildMoreItem(bean, minHeight, maxHeight);
                              }).toList()
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              ]
          ),
        ),
      ),
    );
  }

  _verticalDragUpdate(DragUpdateDetails details,WeatherBean bean, double minHeight, double maxHeight) {
    _offsetOneDayExplore -= details.delta.dy;
    if (_offsetOneDayExplore > maxHeight) {
      _offsetOneDayExplore = maxHeight;
    }
    if(_offsetOneDayExplore > -maxHeight) {
      _selectedDayKey = bean.date ;
      if(_offsetOneDayExplore < 0) {
        _otherDayOffsetX = (_offsetOneDayExplore + maxHeight) / maxHeight;
      }else {
        _otherDayOffsetX = _offsetOneDayExplore / maxHeight;
      }
      _scrollToIndex(_selectedDayKey);
      setState(() {});
    }
    print("offsetExplore  $_offsetOneDayExplore");
  }

  _onVerticalDragEnd(DragEndDetails details, double maxHeight) {

    if(_offsetOneDayExplore > maxHeight / 2) {
      _otherDayOffsetX = 1.0;
      _otherDayExpand = true ;
    } else {
      _otherDayOffsetX = 0.0;
      _otherDayExpand = false;
    }
    _offsetOneDayExplore = 0.0;

    _animationNotCompleted = false ;
    setState(() {});
  }

  Widget _buildMoreItem(WeatherBean bean, double minHeight, double maxHeight) {
    var offset = _selectedDayKey == bean.date ? _otherDayOffsetX: 0.0 ;
    return Padding(
      padding: EdgeInsets.only(right: 10.0 - offset * 10.0),
            child: GestureDetector(
              onTap: (){_otherOpen(bean.date);},
              onVerticalDragUpdate: (details){_verticalDragUpdate(details, bean, minHeight,maxHeight);},
              onVerticalDragEnd: (details) {_onVerticalDragEnd(details, maxHeight);},
              child: Container(
                width: 130.0 + offset * (_screenWidth - 130.0),
                height: 150.0 + offset * (maxHeight - 150.0),

                child: DecoratedBox(
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.all(Radius.circular(10.0)),
                    color: Color(bean.color),
                  ),
                  child: SizedBox(
                    width: 130.0 + offset * (_screenWidth - 130.0),
                    child: Column(
                      mainAxisAlignment: MainAxisAlignment.spaceAround,
                      children: <Widget>[
                        SizedBox(height: 27.0,),
                        Text(bean.date, style: TextStyle(
                            color: Color(0xFFFFFFFF),
                            fontSize: 14.0 + offset * (47.0 - 14.0),
                            fontWeight: FontWeight.bold),),
                        Transform.rotate(
                          angle: bean.type == "images/sun.png" ? pi * offset * 19.9 : 0.0,
                          child: Image.asset(
                            bean.type, width: 50.0 + offset * (160.0 - 50.0),
                            height: 50.0 + offset * (160.0 - 50.0),),
                        ),
                        Text("${bean.average}°", style: TextStyle(
                            color: Color(0xFFFFFFFF),
                            fontSize: 27.0 + offset * (61.0 - 27.0)),),
                        Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: <Widget>[
                            Text("${bean.min}°", style: TextStyle(
                                color: Color(0xFFFFFFFF),
                                fontSize: 14.0 + offset * (30.0 - 14.0),
                                fontWeight: FontWeight.bold),),
                            SizedBox(width: 10.0,),
                            Text("${bean.max}°", style: TextStyle(
                                color: Color(0xFFFFFFFF),
                                fontSize: 14.0 + offset * (30.0 - 14.0),
                                fontWeight: FontWeight.bold),),
                          ],
                        ),
                        SizedBox(height: 6.0,),
                        _buildMoreTimeWeather(offset)
                      ],
                    ),
                  ),
                ),
              ),
            ),
    );
  }

  Expanded _buildMoreTimeWeather(double offset) {
    var opacity = offset > 0.9 ? offset: 0.0;
    return Expanded(
                      flex: 1,
                      child: Padding(
                        padding: const EdgeInsets.all(20.0),
                        child: Opacity(
                          opacity: opacity,
                          child: DecoratedBox(
                            decoration: BoxDecoration(
                              color: Colors.white,
                              borderRadius: BorderRadius.all(
                                  Radius.circular(20.0)),
                            ),
                            child: SizedBox(
                              height: double.infinity,
                              width: double.infinity,
                              child: Column(
                                mainAxisAlignment: MainAxisAlignment.center,
                                children: <Widget>[
                                  Expanded(flex: 1,
                                    child: Padding(
                                      padding: const EdgeInsets.all(20.0),
                                      child: Row(
                                        mainAxisAlignment: MainAxisAlignment.spaceAround,

                                        children: WeatherBean.getDefaultTimeData().map((timeBean){
                                          return Column(
                                            mainAxisAlignment: MainAxisAlignment.spaceAround,
                                            children: <Widget>[
                                              Text(timeBean.date, style: TextStyle(color: Color(0xFF333333), fontSize: 14.0 ,fontWeight: FontWeight.bold),),
                                              Image.asset(timeBean.type, width: 30.0, height: 30.0),
                                              Text("${timeBean.average}°", style: TextStyle(color: Color(0xFFDAEFFC), fontSize: 14.0),),

                                            ],
                                          );
                                        }).toList(),
                                      ),
                                    )
                                  ),
                                  SizedBox(
                                      height: 1.0,
                                      width: double.infinity,
                                    child: DecoratedBox(
                                        decoration: BoxDecoration(
                                          borderRadius: BorderRadius.all(Radius.circular(10.0)),
                                          color: Color(0xFFDAEFFC),
                                        )
                                    )
                                  ),
                                  Center(
                                    child: SizedBox(
                                      height: 40.0,
                                      child: Center(
                                        child: Text("Carry Umbrella", style: TextStyle(color: Color(0xFF130E51), fontSize: 17.0, fontWeight: FontWeight.bold),),
                                      ),
                                    ),
                                  )
                                ],
                              ),
                            ),
                          ),
                        ),
                      )
                    );
  }

  int _getScrollViewIndex(String key) {
    for(int i=0;i<  WeatherBean.getDefaultDateData().length; i++) {
      if(WeatherBean.getDefaultDateData()[i].date == key) {
        return i ;
      }
    }
    return 0 ;
  }

  @override
  void dispose() {
    super.dispose();
    _todayController?.dispose();
    _otherDayController?.dispose();
  }
}